<?php
/**
 * CreateUser: zlh
 * CreateTime: 2022/1/20 15:41
 * Remark:
 */

namespace App\Func;

use App\Consts\EncryptConsts\EncryptConsts;
use Illuminate\Support\Facades\Hash;
use JetBrains\PhpStorm\Pure;

class EncryptionFunc
{
    /**
     * 返回哈希加密串
     * @param string $string
     * @return string
     */
    public static function encryptionHash(string $string): string
    {
        return Hash::make($string);
    }

    /**
     * 返回 Bcrypt加密串
     * @param string $string
     * @return string
     */
    public static function encryptionBcrypt(string $string):string{
        return Hash::make($string, [
            #加密系数
            'rounds' => 12,
        ]);
    }

    /**
     * 返回Argon2加密串
     * @param string $string
     * @return string
     */
    public static function encryptionArgon2(string $string):string{
        return Hash::make($string, [
            'memory' => 1024,
            'time' => 2,
            'threads' => 2,
        ]);
    }

    /**
     * 获取Openssl
     * @return string
     */
    public static function getOpensslEncryptAppKey(): string
    {
        return substr(md5(EncryptConsts::ENCRYPT_CONSTS_APP_KEY),8,16);
    }

    /**
     * 获取IV
     * @param $idx
     * @param $timestamp
     * @return string
     */
    public static function getOpensslIv($idx,$timestamp): string
    {
        return substr(md5($idx.$timestamp),0,16);
    }


    /**
     * 解密字符串
     * @param $data
     * @param $iv
     * @return bool|string
     */
    public static function decryptOpenssl($data,$iv): bool|string
    {
        return openssl_decrypt(base64_decode($data), 'AES-128-CBC',self::getOpensslEncryptAppKey(), 1, $iv);
    }

    /**
     * 获取登录签名
     * @param $staffLoginAccount
     * @param $staffLoginPassword
     * @param $companyId
     * @param $timestamp
     * @return string
     */
    #[Pure]
    public static function getLoginSign($staffLoginAccount, $staffLoginPassword, $companyId, $timestamp): string
    {
        return  md5("ACCOUNT=$staffLoginAccount".
            "PWD=$staffLoginPassword".
            "COMPANYID=$companyId".
            "TIMESTAMP=$timestamp".
            "APPKEY=".self::getOpensslEncryptAppKey()
        );
    }

    /**
     * 当前时间20230713 md5 取 16位
     */
    private function getNewIv(){
        return substr(md5(date("Ymd",time())),0,16);
    }

    /**
     * 最新加密方法为 aes128cbc
     * 加密的iv填充为 当前时间20230713 md5 取 16位
     * @param $data
     */
    public function Aes256cbcPkcs7ToBase64Encode($aesKey,$data){
        // 动态IV 根据当前时间20230713 md5 取 16位
        $iv = $this->getNewIv();
        return base64_encode(openssl_encrypt($data, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA, $iv));
    }

    /**
     * 解码
     * @param $data
     * @return false|string
     */
    public function Aes256cbcPkcs7ToBase64Decode($aesKey,$data){
        $iv = $this->getNewIv();
        return openssl_decrypt(base64_decode($data), 'AES-256-CBC',$aesKey, OPENSSL_RAW_DATA, $iv);
    }

    /**
     * RSA BASE64加密
     * @param $puKey
     * @param $data
     */
    public function rsaToBase64Encode($puKey,$data){
        // 加载公钥
        openssl_pkey_get_public($puKey);
        // 使用公钥加密数据
        openssl_public_encrypt($data, $encryptedData, $puKey);
        // 将加密后的数据进行 base64 编码，方便传输
        return base64_encode($encryptedData);

    }

    public function rsaToBase64Decode($pvKey,$data){
        // 加载私钥
        $privateKey = openssl_pkey_get_private($pvKey);
        openssl_private_decrypt(base64_decode($data), $decryptedData, $privateKey);
        return $decryptedData;
    }


    public static function getRSAPuKeyPvKey(){
        // 生成 RSA 密钥对
        $privateKey = openssl_pkey_new([
            'private_key_bits' => 2048, // 密钥位数
            'private_key_type' => OPENSSL_KEYTYPE_RSA, // 密钥类型
        ]);
        // 提取私钥
        openssl_pkey_export($privateKey, $privateKeyString);
        // 提取公钥
        $publicKey = openssl_pkey_get_details($privateKey)['key'];
        return [
            'pu_key' => $publicKey,
            'pv_key' => $privateKeyString
        ];
    }
}